#!/usr/bin/env python3

import threading as _threading

#  Subscribers list.
_SUBSCRIBERS = []

#  Lock.
_LOCK = _threading.Lock()


def add_subscriber(bucket):
    """Add a subscriber.

    :type bucket: tmm.web.mq.bucket.MessageBucket
    :param bucket: The bucket of the subscriber.
    """

    #  Lock.
    _LOCK.acquire()

    #  Check duplication.
    for subscriber in _SUBSCRIBERS:
        if subscriber is bucket:
            _LOCK.release()
            raise ValueError("Duplicated subscriber.")

    #  Add the subscriber.
    _SUBSCRIBERS.append(bucket)

    #  Unlock.
    _LOCK.release()


def remove_subscriber(bucket):
    """Remove a subscriber.

    :type bucket: tmm.web.mq.bucket.MessageBucket
    :param bucket: The bucket of the subscriber.
    """

    #  Lock.
    _LOCK.acquire()

    #  Search and remove the subscriber.
    for idx in range(0, len(_SUBSCRIBERS)):
        if _SUBSCRIBERS[idx] is bucket:
            #  Remove.
            _SUBSCRIBERS.pop(idx)

            #  Unlock.
            _LOCK.release()

            return

    #  Unlock.
    _LOCK.release()

    raise ValueError("No such bucket.")


def publish_message(msg):
    """Publish a message to all subscribers.

    :type msg: bytes
    :param msg: The body of the message.
    """

    #  Lock.
    _LOCK.acquire()

    #  Write the message.
    for subscriber in _SUBSCRIBERS:
        subscriber.write_message(msg)

    #  Unlock.
    _LOCK.release()
